import { _decorator, Component, input, Input, EventTouch, Camera, EventMouse, sys, v3, v2, Vec3, find, Prefab, director, BoxCollider, Node } from 'cc';
import { DEV, PREVIEW } from 'cc/env';
import { CharacterState, PlayerController } from './PlayerController';
import { Panel, UIManager } from './AshFramework/Managers/UIManager';
import { AimController } from './AimController';
import { ResourceUtil } from './AshFramework/Utils/ResourceUtil';
import { GameManager } from './GameManager';
import { NodeUtil } from './AshFramework/Utils/NodeUtil';
import { EnemyController } from './EnemyController';
import { ZTool } from './AshFramework/Utils/ZTool';
import { DataManager } from './AshFramework/Managers/DataManager';
import Banner from './Banner';

const { ccclass, property } = _decorator;

const startPosition = v2();
const targetPosition = v3();

/**
 * 游戏控制器
 */
@ccclass('GameController')
export class GameController extends Component {
    static Instance: GameController = null;

    @property({ type: Camera, displayName: '摄像机' })
    protected camera: Camera = null;

    @property(Node)
    playerPosition: Node = null;

    @property([Node])
    enemys: Node[] = [];

    enemyCtrls: EnemyController[] = [];

    player: PlayerController = null;

    canvas: Node = null;

    maxLength: number = 3;
    scalar: number = 0.01;

    IsShoot: boolean = true;

    private _isRoundPlayer: boolean = false;
    get IsRoundPlayer() { return this._isRoundPlayer; }
    set IsRoundPlayer(value: boolean) {
        if (GameManager.IsGameOver) return;

        if (value) {
            UIManager.GetInstance().ShowPanel(Panel.BattleDeckPanel);
        } else {
            let es = [];

            for (let i = 0; i < this.enemyCtrls.length; i++) {
                if (this.enemyCtrls[i].HP > 0) {
                    es.push(this.enemyCtrls[i])
                }
            }

            if (es.length > 0) {
                let index = ZTool.GetRandomInt(0, es.length);
                es[index].Shoot();
            }
        }

        this._isRoundPlayer = value;
    }

    protected onLoad() {
        GameController.Instance = this;
        GameManager.IsGameOver = false;

        this.registerEvent();

        PREVIEW && (window['gameController'] = this);

        this.canvas = find("Canvas");

        this._isRoundPlayer = false;
        this.IsShoot = true;

        for (let i = 0; i < this.enemys.length; i++) {
            this.enemyCtrls.push(this.enemys[i].getComponent(EnemyController));
        }

        if (Banner.NeedShowMoreAd) {
            Banner.Instance.ShowVideoAd(() => { });
        }

        ResourceUtil.LoadPrefab(`Characters/${GameManager.Instance.GetSelectedHeroIndex()}`).then((prefab: Prefab) => {
            let node = NodeUtil.Instantiate(prefab, director.getScene());
            node.setWorldPosition(this.playerPosition.worldPosition);
            this.player = node.getComponent(PlayerController);
            this.scheduleOnce(() => {
                this.IsRoundPlayer = true;
            }, 1);
        });
    }

    CheckWin() {
        for (let i = 0; i < this.enemyCtrls.length; i++) {
            if (this.enemyCtrls[i].HP > 0) return;
        }

        GameManager.IsGameOver = true;
        DataManager.playerData.EXP += 100;
        UIManager.GetInstance().ShowPanel(Panel.WinPanel);
    }

    Fail() {
        DataManager.playerData.EXP += 50;
        UIManager.GetInstance().ShowPanel(Panel.FailPanel);
    }

    //#region 

    protected onTouchStart(event: EventTouch) {
        if (this.IsRoundPlayer && !this.IsShoot) {
            if (event.getAllTouches().length > 1) {
                return;
            }

            this.player.PlayAni(CharacterState.HandItem);
            startPosition.set(event.getLocation());
        }
    }

    protected onTouchMove(event: EventTouch) {
        if (this.IsRoundPlayer && !this.IsShoot) {
            if (!this.IsRoundPlayer && this.IsShoot) return;

            if (event.getAllTouches().length > 1) return;

            let gap = event.getLocation().subtract(startPosition).multiplyScalar(this.scalar);

            if (gap.length() > this.maxLength) {
                gap.normalize();
                gap.multiplyScalar(this.maxLength);
            }

            targetPosition.set(this.player.aimCtrl.yawAxis.worldPosition.x + gap.x, this.player.aimCtrl.yawAxis.worldPosition.y + gap.y, 0);
            this.player.aimCtrl.aim(targetPosition);
        }
    }

    protected onTouchEnd(event: EventTouch) {
        if (this.IsRoundPlayer && !this.IsShoot) {
            if (!this.IsRoundPlayer && this.IsShoot) return;

            if (event.getAllTouches().length > 0) {
                return;
            }
            this.player.PlayAni(CharacterState.Throw);
            this.player.aimCtrl.trajectoryDrawer.clear();
            this.player.aimCtrl.fire();
        }
    }

    //#endregion

    protected onDestroy() {
        this.unregisterEvent();
    }

    protected registerEvent() {
        input.on(Input.EventType.TOUCH_START, this.onTouchStart, this);
        input.on(Input.EventType.TOUCH_MOVE, this.onTouchMove, this);
        input.on(Input.EventType.TOUCH_END, this.onTouchEnd, this);
    }

    protected unregisterEvent() {
        input.off(Input.EventType.TOUCH_START, this.onTouchStart, this);
        input.off(Input.EventType.TOUCH_MOVE, this.onTouchMove, this);
        input.off(Input.EventType.TOUCH_END, this.onTouchEnd, this);
    }

    WorldToScreen(worldPosition: Vec3): Vec3 {
        return this.camera.convertToUINode(worldPosition, this.canvas);
    }

}
